/* Copyright (c) 2011 Frank Zhao
   All rights reserved.

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   * Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
   * Neither the name of the authors nor the names of its contributors
     may be used to endorse or promote products derived from this software
     without specific prior written permission.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. */

#ifndef PalmQuadRadio_h

#include "ZigduinoRadioCfg.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "radio.h"
#include "board.h"
#include "transceiver.h"

#ifdef __cplusplus
} // extern "C"
#endif

// device address definitions
#define PQR_FLIER_DEVADDR 0x12
#define PQR_CTRLER_DEVADDR 0x34
#define PQR_RCCHAN_CNT 6 // number of RC channels
#define PQR_RFCHAN_MAX 3 // should be 16 in theory
#define PQR_RFCHAN_START 11

// these button maps correspond with the bits of the Wii Classic Controller button bytes
//  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
// 4| BDR | BDD | BLT | B-  | BH  | B+  | BRT |  1  |
// 5| BZL | BY  | BY  | BA  | BX  | BZR | BDL | BDU |
#define PQC_ARM 10
#define PQC_DISARM 12
#define PQC_ZEROSENSORS 3
#define PQC_ACROMODE 9
#define PQC_STABLEMODE 2
#define PQC_SYNCCHAN 4
#define PQC_WIICALI 5
#define PQC_ACCTRIM 7
#define PQC_ACCTRIMUP 0
#define PQC_ACCTRIMDOWN 14
#define PQC_ACCTRIMLEFT 1
#define PQC_ACCTRIMRIGHT 15

#define PQF_LED1_ON()  PORTF |= _BV(2)
#define PQF_LED1_TOG() PORTF ^= _BV(2)
#define PQF_LED1_OFF() PORTF &= ~_BV(2)
#define PQF_LED2_ON()  PORTE |= _BV(2)
#define PQF_LED2_TOG() PORTE ^= _BV(2)
#define PQF_LED2_OFF() PORTE &= ~_BV(2)

#define PQS_LED1_ON()  PORTF |= _BV(2)
#define PQS_LED1_TOG() PORTF ^= _BV(2)
#define PQS_LED1_OFF() PORTF &= ~_BV(2)
#define PQS_LED2_ON()  PORTF |= _BV(3)
#define PQS_LED2_TOG() PORTF ^= _BV(3)
#define PQS_LED2_OFF() PORTF &= ~_BV(3)
#define PQS_LED3_ON()  PORTF |= _BV(4)
#define PQS_LED3_TOG() PORTF ^= _BV(4)
#define PQS_LED3_OFF() PORTF &= ~_BV(4)

#ifdef __cplusplus
#include <Stream.h>
#include <Print.h>

// just a class definition, for usage and comments, see the c/cpp file
class cPalmQuadRadio : public Stream
{
    private:
    public:
        cPalmQuadRadio();
        void begin(uint8_t);
        void requestDiscovery();
        uint8_t hasDiscovered();
        void setChannel(channel_t chan);
        void sendFlightCommands();
        void setRxMode();
        uint8_t rand();
        uint8_t isPresent();
        void setFlushOnNext();
        virtual int available(void);
        virtual int peek(void);
        virtual int read(void);
        virtual void flush(void);
        void flushTx(void);
        virtual void write(uint8_t);
        using Print::write; // pull in write(str) and write(buf, size) from Print
};

extern cPalmQuadRadio PalmQuadRadio; // make single instance accessible

#else

// function prototypes if compiled as C
void pqr_begin(uint8_t);
void pqr_requestDiscovery();
uint8_t pqr_hasDiscovered();
int pqr_available(void);
int pqr_peek(void);
int pqr_read(void);
void pqr_flush(void);
uint8_t pqr_rand();
uint8_t pqr_isPresent();
void pqr_setFlushOnNext();

#endif

// function prototypes for both C and C++
void pqr_flushTx(void);
void pqr_write(uint8_t);
void pqr_setRxMode(void);

extern volatile uint16_t pqr_rcChan[PQR_RCCHAN_CNT]; // load or read RC channels from here

#define PalmQuadRadio_h
#endif